package com.pedro.streamer.service;

import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;

import com.pedro.streamer.R;
import com.pedro.streamer.manager.MediaPlayerClient;
import com.pedro.streamer.model.AudioItem;
import com.pedro.streamer.view.AudioControlView;
import com.pedro.streamer.view.FilterSourceView;
import com.pedro.streamer.view.FloatingView;
import com.pedro.streamer.view.SoundSourceView;
import com.pedro.streamer.view.VideoControlView;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class FloatingMediaService extends Service implements View.OnClickListener {

    private static final String TAG = "FloatingMediaService";
    public static boolean isStarted = false;
    private WindowManager windowManager;
    private WindowManager.LayoutParams layoutParams;

    private WindowManager.LayoutParams controllerLayoutParams;
    private static FloatingView floatingView;
    private static ConstraintLayout constraintLayout;

    private static VideoControlView videoControlView;
    private AudioControlView audioControlView;

    private FilterSourceView filterSourceView;

    private SoundSourceView soundSourceView;

    private MediaPlayer supMediaPlayer;
    private MediaPlayer bgmMediaPlayer;
    private List<AudioItem> audioList;
    private List<AudioItem> bgmList;
    private MediaPlayerClient.PlayMode mPlayMode;
    private boolean letMusicPlay = false;
    private boolean letBgmPlay = false;
    private long delayTime = 10000;
    private int currentSongIndex;
    private int currentBgmIndex;
    private Random random = new Random();
    private Timer timer;
    private boolean isTimerOn;

    @Override
    public void onCreate() {
        super.onCreate();
        super.onCreate();
        isStarted = true;
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        supMediaPlayer = new MediaPlayer();
        bgmMediaPlayer = new MediaPlayer();
        audioList = new ArrayList<>();
        bgmList = new ArrayList<>();
        supMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
                Log.e(TAG, "助播onError: " + i + " " + i1);
                return false;
            }
        });
        supMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mediaPlayer) {

                Log.d(TAG, "onCompletion: 当前延时播放时间：" + delayTime);

                if (!isTimerOn) {
                    timer = new Timer();
                }
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        if (letMusicPlay) {
                            if (mPlayMode == MediaPlayerClient.PlayMode.RandomPlay) {
                                Log.d(TAG, "随机下一曲");
                                playRandomSong();
                            } else {
                                Log.d(TAG, "播放下一曲");
                                next();
                            }
                        }
                    }
                }, delayTime);
                isTimerOn = true;
            }
        });
        bgmMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
                Log.e(TAG, "bgm onError: " + i + " " + i1);
                return false;
            }
        });
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand: 悬浮窗服务启动了");
        supMediaPlayer.setVolume(0.5f, 0.5f);
        bgmMediaPlayer.setVolume(0.5f, 0.5f);
        MediaPlayerClient.getInstance(this).bindService(intent);
        showFloatingWindow();
        return START_STICKY;
    }

    private void showFloatingWindow() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (Settings.canDrawOverlays(this)) {
                windowManager.addView(getConstraintLayout(), getControllerLayoutParams());
                windowManager.addView(getFloatingView(), getFloatingLayoutParams());
                floatingView.setVisibility(View.GONE);
                constraintLayout.setVisibility(View.GONE);

                videoControlView = constraintLayout.findViewById(R.id.video_manager_layout);
                soundSourceView = constraintLayout.findViewById(R.id.audio_manager_layout);
                audioControlView = soundSourceView.findViewById(R.id.audio_control_layout);
                filterSourceView = constraintLayout.findViewById(R.id.video_filter_layout);

            }
        }
    }

    public List<AudioItem> getAudioList() {
        return audioList;
    }

    public List<AudioItem> getBgmList() {
        return bgmList;
    }

    private ConstraintLayout getConstraintLayout() {
        if (constraintLayout != null) {
            return constraintLayout;
        }
        constraintLayout = (ConstraintLayout) LayoutInflater.from(this).inflate(R.layout.controller_window_layout, null);
        return constraintLayout;

    }

    private FloatingView getFloatingView() {
        if (floatingView != null) {
            return floatingView;
        }
        floatingView = (FloatingView) LayoutInflater.from(this).inflate(R.layout.float_view, /* root= */ null);
        floatingView.setOnTouchListener(new FloatingOnTouchListener());

        if (floatingView == null) {
            throw new IllegalStateException(
                    "R.layout.navigation_panel could not be properly inflated");
        }
        return floatingView;
    }

    private WindowManager.LayoutParams getFloatingLayoutParams() {
        layoutParams = new WindowManager.LayoutParams();
        layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        layoutParams.format = PixelFormat.RGBA_8888;
        layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
        layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;

        return layoutParams;
    }


    private WindowManager.LayoutParams getControllerLayoutParams() {
        controllerLayoutParams = new WindowManager.LayoutParams();
        controllerLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        controllerLayoutParams.format = PixelFormat.RGBA_8888;
        controllerLayoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM;
        controllerLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        controllerLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
        controllerLayoutParams.height = 283 * 3;

        return controllerLayoutParams;
    }

    public boolean isLetMusicPlay() {
        return letMusicPlay;
    }

    public void setLetMusicPlay(boolean letMusicPlay) {
        this.letMusicPlay = letMusicPlay;
    }

    public boolean isLetBgmPlay() {
        return letBgmPlay;
    }

    public void setLetBgmPlay(boolean letBgmPlay) {
        this.letBgmPlay = letBgmPlay;
    }

    public MediaPlayer getMediaPlayer() {
        return supMediaPlayer;
    }

    public MediaPlayer getBgmMediaPlayer() {
        return bgmMediaPlayer;
    }

    public void setSupVolume(float a, float b) {
        supMediaPlayer.setVolume(a, a);
        audioControlView.updateSupVolume((int) (a * 100));
    }

    public void updatePlayList(List<AudioItem> audioItems) {
        audioList = audioItems;
    }

    public void updateBgmList(List<AudioItem> audioItems) {
        bgmList = audioItems;
    }

    public void prepareMediaPlayer(int songIndex) {

        supMediaPlayer.reset();
        if (audioList.size() == 0) {
            return;
        }
        Log.d(TAG, "prepareMediaPlayer: " + audioList.get(songIndex).getAudioName() + ":" + audioList.get(songIndex).getAudioFilePath());
        try {
            supMediaPlayer.setDataSource("file://" + audioList.get(songIndex).getAudioFilePath());
            supMediaPlayer.prepare();
        } catch (Exception e) {
            Log.e(TAG, "prepareMediaPlayer: " + e.getMessage());
        }
    }

    public void prepareBgmPlayer(int bgmIndex) {
        bgmMediaPlayer.reset();
        if (bgmList.size() == 0) {
            return;
        }
        Log.d(TAG, "prepareBgmPlayer: " + bgmList.get(bgmIndex).getAudioFilePath());
        try {
            bgmMediaPlayer.setDataSource("file://" + bgmList.get(bgmIndex).getAudioFilePath());
            bgmMediaPlayer.prepare();
        } catch (Exception e) {

        }
        bgmMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mediaPlayer) {
                nextBgm();
            }
        });
    }

    private void playRandomSong() {
        if (audioList.size()  == 0) {
            return;
        }
        int randomIndex = random.nextInt(audioList.size());
        prepareMediaPlayer(randomIndex);
        play();
        currentSongIndex = randomIndex;
    }

    private void play() {
        if (supMediaPlayer != null) {
            supMediaPlayer.start();
            audioControlView.updateMusicTitle(audioList.get(currentSongIndex).getAudioName(), audioList.get(currentSongIndex).getFileName());
        }
    }

    private void bgmPlay() {
        if (bgmMediaPlayer != null) {
            bgmMediaPlayer.start();
            letBgmPlay = true;
        }
    }

    private void pre() {
        if (audioList.size() == 0) {
            return;
        }
        currentSongIndex = (currentSongIndex - 1 + audioList.size()) % audioList.size();
        prepareMediaPlayer(currentSongIndex);
        play();
    }

    private void next() {
        if (audioList.size() == 0) {
            return;
        }
        currentSongIndex = (currentSongIndex + 1) % audioList.size();
        prepareMediaPlayer(currentSongIndex);
        play();
    }

    private void nextBgm() {
        currentBgmIndex = (currentBgmIndex + 1) % bgmList.size();
        prepareBgmPlayer(currentBgmIndex);
        bgmPlay();
    }

    public void playPreMusic() {
        if (timer != null) {
            timer.cancel();
        }
        isTimerOn = false;
        pre();
    }

    public void playNextMusic() {
        if (timer != null) {
            timer.cancel();
        }
        isTimerOn = false;
        next();
    }
    public void playOrPause(boolean isOpen) {
        Log.d(TAG, "muscPlayOrPause: ");
        if (audioList.size() == 0) {
            return;
        }
        if (supMediaPlayer != null) {
            if (isOpen) {
                playRandomSong();
            } else {
                if (timer != null) {
                    timer.cancel();
                }
                isTimerOn = false;
                supMediaPlayer.stop();
            }
        }
        letMusicPlay = isOpen;
        audioControlView.updateIsPlaying(letMusicPlay);
    }

    private void playOrPauseBgm(boolean isOpen) {
        letBgmPlay = isOpen;
        if (bgmMediaPlayer != null) {
            letBgmPlay = isOpen;
            if (isOpen) {
//                prepareBgmPlayer(0);
//                bgmPlay();
                playRandomSong();
            } else {
                bgmMediaPlayer.stop();
            }
        }
    }

    public void setSupPlayMode(MediaPlayerClient.PlayMode playMode) {
        mPlayMode = playMode;
        audioControlView.updatePlayMode(playMode);
    }

    public void setDelayTime(long delayTime) {
        Log.d(TAG, "setDelayTime: 设置了延迟时间" + delayTime);
        this.delayTime = delayTime;
        audioControlView.updateDelayTime(delayTime);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new FloatingBinder(this);
    }

    @Override
    public void onClick(View view) {

    }


    public class FloatingBinder extends Binder {

        private FloatingMediaService mFloatingMediaService;

        public MediaPlayer getSupMediaPlayer() {
            return mFloatingMediaService.getMediaPlayer();
        }

        public boolean isLetMusicPlay() {
            return mFloatingMediaService.isLetMusicPlay();
        }

        public boolean isLetBgmPlay() {
            return mFloatingMediaService.isLetBgmPlay();
        }

        public void updateLetMusicPlay(boolean isLetMusicPlay) {
            mFloatingMediaService.setLetMusicPlay(isLetMusicPlay);
        }

        public void updateMusicVolume(float a, float b) {
            mFloatingMediaService.setSupVolume(a, b);
        }

        public void updateBgmVolume(float a, float b) {
            mFloatingMediaService.getBgmMediaPlayer().setVolume(a, b);
        }

        public FloatingBinder(FloatingMediaService floatingMediaService) {
            mFloatingMediaService = floatingMediaService;
        }

        public void updatePlayList(List<AudioItem> audioItems) {
            mFloatingMediaService.updatePlayList(audioItems);
        }

        public void updateBgmPlayList(List<AudioItem> audioItems) {
            mFloatingMediaService.updateBgmList(audioItems);
        }

        public void playRandomMusic(boolean isOpen) {
            mFloatingMediaService.playOrPause(isOpen);
        }

        public void playBgmMusic(boolean isOpen) {
            mFloatingMediaService.playOrPauseBgm(isOpen);
        }

        public void playBgmAtPosition(int position) {
            mFloatingMediaService.prepareBgmPlayer(position);
            mFloatingMediaService.bgmPlay();
        }

        public void playPre() {
            mFloatingMediaService.playPreMusic();
        }

        public void playNext() {
            mFloatingMediaService.playNextMusic();
        }

        public void updateRandomState(MediaPlayerClient.PlayMode playMode) {
            mFloatingMediaService.setSupPlayMode(playMode);
        }

        public void updateDelayTime(long time) {
            mFloatingMediaService.setDelayTime(time);
        }

        public List<AudioItem> getBgmList() {
            return mFloatingMediaService.getBgmList();
        }

        public List<AudioItem> getMusicList() {
            return mFloatingMediaService.getAudioList();
        }

        public void syncAudioControlViewData() {

        }

        /**
         * videoManager
         */

        public void showAudioView() {

            mFloatingMediaService.showAudioView();

        }

        public void showFloatView(boolean bool) {
            mFloatingMediaService.showFloatingView(bool);
        }

        public void showControl() {
            mFloatingMediaService.showControl();
        }

        public void showVideoView() {
            mFloatingMediaService.showVideoView();
        }

        public void showClipView() {
            mFloatingMediaService.showClipView();
        }
    }


    public void showClipView() {
        Log.d(TAG, "showClipView: ");
        filterSourceView.setVisibility(View.VISIBLE);
        filterSourceView.reloadView();
    }
    private void showAudioView() {
        filterSourceView.setVisibility(View.GONE);
        videoControlView.setVisibility(View.GONE);
        soundSourceView.setVisibility(View.VISIBLE);

    }


    private class FloatingOnTouchListener implements View.OnTouchListener {
        private int x;
        private int y;

        @Override
        public boolean onTouch(View view, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    x = (int) event.getRawX();
                    y = (int) event.getRawY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    int nowX = (int) event.getRawX();
                    int nowY = (int) event.getRawY();
                    int movedX = nowX - x;
                    int movedY = nowY - y;
                    x = nowX;
                    y = nowY;
                    layoutParams.x = layoutParams.x + movedX;
                    layoutParams.y = layoutParams.y + movedY;
                    windowManager.updateViewLayout(view, layoutParams);
                    break;
                default:
                    break;
            }
            return false;
        }
    }


    public void showControl() {

        if (floatingView.getVisibility() == View.VISIBLE) {
            if (constraintLayout.getVisibility() == View.GONE) {
                constraintLayout.setVisibility(View.VISIBLE);
                if (MediaPlayerClient.getInstance(this).getVideoSyncListen() != null){
                    MediaPlayerClient.getInstance(this).getVideoSyncListen().videoSync();
                }
                if (videoControlView != null) {
                    videoControlView.setVideoPicArr();
                }
            } else if (constraintLayout.getVisibility() == View.VISIBLE) {
                constraintLayout.setVisibility(View.GONE);
            }
        }


    }

    public void showFloatingView(boolean bool) {
        //floatingView 隐藏时constraintLayout 一定是隐藏的
        if (floatingView != null) {
            if (bool) {
                floatingView.setVisibility(View.VISIBLE);
            } else {
                floatingView.setVisibility(View.GONE);
                constraintLayout.setVisibility(View.GONE);
            }
        }


    }


    public void showVideoView() {
        filterSourceView.setVisibility(View.GONE);
        videoControlView.setVisibility(View.VISIBLE);
        soundSourceView.setVisibility(View.GONE);


    }

}
